package com.zjh.photoshopstudy.app.upload;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.text.format.Formatter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.lzy.okgo.convert.StringConvert;
import com.lzy.okgo.db.UploadManager;
import com.lzy.okgo.model.Progress;
import com.lzy.okgo.request.base.Request;
import com.lzy.okserver.OkUpload;
import com.lzy.okserver.download.DownloadTask;
import com.lzy.okserver.task.XExecutor;
import com.lzy.okserver.upload.UploadListener;
import com.lzy.okserver.upload.UploadTask;
import com.zjh.photoshopstudy.Model.VideoEntity;
import com.zjh.photoshopstudy.R;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class UploadingAdapter extends RecyclerView.Adapter<UploadingAdapter.UploadingView> {

    private List<UploadTask<?>> values = new ArrayList<>();
    private Context context;
    private NumberFormat numberFormat;
    private XExecutor.OnAllTaskEndListener OnAllTaskEndListener;

    public UploadingAdapter(Context context, XExecutor.OnAllTaskEndListener onAllTaskEndListener) {
        this.context = context;
        numberFormat = NumberFormat.getPercentInstance();
        numberFormat.setMinimumFractionDigits(2);
        OnAllTaskEndListener = onAllTaskEndListener;
    }

    public void updateData() {
        values = OkUpload.restore(UploadManager.getInstance().getUploading());

        //由于Converter是无法保存下来的，所以这里恢复任务的时候，需要额外传入Converter，否则就没法解析数据
        //至于数据类型，统一就行，不一定非要是String
        for (UploadTask<?> task : values) {
            //noinspection unchecked
            Request<String, ? extends Request> request = (Request<String, ? extends Request>) task.progress.request;
            request.converter(new StringConvert());
        }
        if (values.size() == 0) {
            OnAllTaskEndListener.onAllTaskEnd();
        }
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public UploadingView onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new UploadingView(LayoutInflater.from(parent.getContext()).inflate(R.layout.downloading_item, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull UploadingView holder, int position) {
        //noinspection unchecked
        UploadTask<String> task = (UploadTask<String>) values.get(position);
        String tag = task.progress.tag;
        task.register(new ListUploadListener(tag, holder))//
                .register(new LogUploadListener<String>());
        holder.setTag(tag);
        holder.setTask(task);
        holder.bind();
        holder.refresh(task.progress);
    }

    public void unRegister() {
        Map<String, UploadTask<?>> taskMap = OkUpload.getInstance().getTaskMap();
        for (UploadTask<?> task : taskMap.values()) {
            task.unRegister(task.progress.tag);
        }
    }

    @Override
    public int getItemCount() {
        return values == null ? 0 : values.size();
    }

    public class UploadingView extends RecyclerView.ViewHolder {
        ImageView image;
        ImageView start;
        ImageView delete;
        ImageView revert;
        ProgressBar progressBar;
        TextView title;
        TextView size;
        TextView tvProgress;
        TextView netSpeed;

        private UploadTask<?> task;
        private String tag;

        public void setTask(UploadTask task) {
            this.task = task;
        }

        public String getTag() {
            return tag;
        }

        public void setTag(String tag) {
            this.tag = tag;
        }

        public void bind() {
            Progress progress = task.progress;
            VideoEntity item = (VideoEntity) progress.extra1;
            Glide.with(context).load(item.getvThumbnailPath()).into(image);
            title.setText(item.getvTitle());
        }

        public UploadingView(@NonNull View itemView) {
            super(itemView);
            image = itemView.findViewById(R.id.imageView5);
            start = itemView.findViewById(R.id.imageView8);
            delete = itemView.findViewById(R.id.imageView7);
            revert = itemView.findViewById(R.id.imageView6);
            progressBar = itemView.findViewById(R.id.progressBar);
            title = itemView.findViewById(R.id.title3);
            size = itemView.findViewById(R.id.size);
            tvProgress = itemView.findViewById(R.id.progress);
            netSpeed = itemView.findViewById(R.id.netSpeed);
            start.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Progress progress = task.progress;
                    switch (progress.status) {
                        case Progress.PAUSE:
                        case Progress.NONE:
                        case Progress.ERROR:
                            task.start();
                            break;
                        case Progress.LOADING:
                            task.pause();
                            break;
                    }
                    refresh(progress);
                }
            });
            delete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    task.remove();
                    updateData();
                }
            });
            revert.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    task.restart();
                }
            });
        }

        public void refresh(Progress progress) {
            String currentSize = Formatter.formatFileSize(context, progress.currentSize);
            String totalSize = Formatter.formatFileSize(context, progress.totalSize);
            size.setText(currentSize + "/" + totalSize);
            switch (progress.status) {
                case Progress.NONE:
                    netSpeed.setText("停止");
                    start.setImageDrawable(context.getResources().getDrawable(android.R.drawable.ic_media_play));
                    break;
                case Progress.PAUSE:
                    netSpeed.setText("暂停中");
                    start.setImageDrawable(context.getResources().getDrawable(android.R.drawable.ic_media_play));
                    break;
                case Progress.ERROR:
                    netSpeed.setText("上传出错");
                    start.setImageDrawable(context.getResources().getDrawable(android.R.drawable.stat_notify_error));
                    break;
                case Progress.WAITING:
                    netSpeed.setText("等待中");
                    start.setImageDrawable(context.getResources().getDrawable(android.R.drawable.ic_menu_recent_history));
                    break;
                case Progress.LOADING:
                    String speed = Formatter.formatFileSize(context, progress.speed);
                    netSpeed.setText(String.format("%s/s", speed));
                    start.setImageDrawable(context.getResources().getDrawable(android.R.drawable.ic_media_pause));
                    break;
            }
            tvProgress.setText(numberFormat.format(progress.fraction));
            progressBar.setMax(10000);
            progressBar.setProgress((int) (progress.fraction * 10000));
        }
    }

    private class ListUploadListener extends UploadListener<String> {

        private UploadingView holder;

        ListUploadListener(Object tag, UploadingView holder) {
            super(tag);
            this.holder = holder;
        }

        @Override
        public void onStart(Progress progress) {
        }

        @Override
        public void onProgress(Progress progress) {
            if (tag == holder.getTag()) {
                holder.refresh(progress);
            }
        }

        @Override
        public void onError(Progress progress) {
            Throwable throwable = progress.exception;
            if (throwable != null) throwable.printStackTrace();
        }

        @Override
        public void onFinish(String s, Progress progress) {
            Toast.makeText(context, "上传完成", Toast.LENGTH_SHORT).show();
            updateData();
        }

        @Override
        public void onRemove(Progress progress) {
        }
    }
}
